package com.hezuti.common.utils;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.nio.channels.FileChannel;
import java.util.Arrays;

import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * 文件 工具类
 * 
 * @author xiaoyu.dou
 * 
 */
public class FileUtil {

    static final Log log = LogFactory.getLog(FileUtil.class);

    /**
     * 移动
     * 
     * @param src
     * @param dest
     */
    public static void mv(File src, File dest) {
	try {
	    if (!src.exists()
		    || src.getCanonicalPath().equals(dest.getCanonicalPath()))
		return;
	} catch (IOException ex) {
	}
	src.renameTo(dest);
    }

    /**
     * copy
     * 
     * @param src
     * @param dest
     */
    public static void cp(File src, File dest) {
	FileInputStream in = null;
	FileOutputStream out = null;

	try {
	    in = new FileInputStream(src);
	    out = new FileOutputStream(dest);
	    FileChannel inChannel = in.getChannel();
	    FileChannel outChannel = out.getChannel();
	    int write = 0;
	    long read = inChannel.size();
	    while (write < read) {
		write += inChannel.transferTo(write, read - write, outChannel);
	    }
	} catch (FileNotFoundException e) {
	    log.error(FileUtil.class.getName() + "#cp FileNotFoundException", e);
	} catch (IOException e) {
	    log.error(FileUtil.class.getName() + "#cp IOException", e);
	} finally {
	    try {
		if (in != null)
		    in.close();
	    } catch (IOException e) {
		log.error(
			FileUtil.class.getName() + "#cp close in IOException",
			e);
	    }
	    try {
		if (out != null)
		    out.close();
	    } catch (IOException e) {
		log.error(FileUtil.class.getName()
			+ "#cp close out IOException", e);
	    }
	}
    }

    /**
     * 判断给定的路径是否为目录
     * 
     * @param dirpath
     * @return
     */
    public static boolean isDirectory(String dirpath) {
	File dir = new File(dirpath);
	return dir.isDirectory();
    }

    /**
     * 列出某个目录下的文件(按照filter进行过滤,最多列出max个文件)
     * 
     * @param dir
     * @param filter
     * @param max
     * @return
     */
    public static File[] listFiles(String dirpath, FilenameFilter filter,
	    int max) {
	if (!isDirectory(dirpath))
	    return null;
	File dir = new File(dirpath);
	File[] files = dir.listFiles(filter);
	if (ArrayUtils.isEmpty(files))
	    return null;
	Arrays.sort(files);
	int end = max < files.length ? max : files.length;
	return (File[]) ArrayUtils.subarray(files, 0, end);
    }

    /**
     * 删除
     * 
     * @param file
     * @return
     */
    public static boolean del(File file) {
	if (file.exists()) {
	    return file.delete();
	}
	return false;
    }

    public static Reader getFileReader(String path, String encode)
	    throws UnsupportedEncodingException, FileNotFoundException {
	return new BufferedReader(new InputStreamReader(new FileInputStream(
		path), encode));
    }

    public static String getFileContent(String path, String encode)
	    throws IOException {
	BufferedReader in = (BufferedReader) getFileReader(path, encode);
	StringBuffer result = new StringBuffer();
	String line;
	try {
	    while ((line = in.readLine()) != null) {
		result.append(line).append("\n");
	    }
	} catch (IOException e) {
	    throw e;
	} finally {
	    if (in != null) {
		in.close();
	    }
	}
	return result.toString();
    }

    public static void setFileContent(String path, String content, String encode)
	    throws IOException {
	File file = new File(path);
	Writer out = new OutputStreamWriter(new FileOutputStream(file), encode);
	try {
	    out.write(content);
	} catch (IOException e) {
	    throw e;
	} finally {
	    if (out != null) {
		out.close();
	    }
	}
    }
}
